/***********************************************
 **** 版权声明处 **
 ****  为了方便阅读和维护，请严格遵守相关代码规范，谢谢   ****
 *******************************************/
package com.hnisi
{
	import com.hnisi.decorators.AlignmentDecorator;
	import com.hnisi.decorators.DecoratorManager;
	import com.hnisi.decorators.DrawMouseMoveRect;
	import com.hnisi.events.DiagramEditorEvent;
	import com.hnisi.events.GraphEvent;
	import com.hnisi.events.SelectionEvent;
	import com.hnisi.skins.NetworkLinkSkin;
	
	import flash.display.DisplayObjectContainer;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.ui.Keyboard;
	
	import mx.collections.ArrayCollection;
	import mx.core.FlexGlobals;
	import mx.core.IVisualElementContainer;
	import mx.core.UIComponent;
	import mx.events.DragEvent;
	import mx.events.FlexEvent;
	import mx.events.SandboxMouseEvent;
	
	import spark.components.supportClasses.SkinnableComponent;
	
	import utils.LicenseHandler;

	/*******************************************
	 **** @author huangjixin
	 **** @date 2012-6-18,上午11:14:06 **
	 **** 图表存放  **
	 *******************************************/
	public class Diagram extends SkinnableComponent
	{
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 类私有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：private static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 类公有静态变量和静态常量声明处。（全部大写，使用下划线进行分割）
		// 例如：public static const EXAMPLE:String = "example";
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		[SkinPart]
		/**
		 * 对应皮肤当中的graph引用 
		 */
		public var graph:Graph;
		
		[SkinPart]
		/**
		 * 绘制层引用 
		 */
		public var drawingLayer:UIComponent;
		
		protected var decoratorManager:DecoratorManager;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// private 私有变量声明处，请以“_”开头定义变量
		// 例如：private var _example:String;
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		private var _showGrid:Boolean = true; 	  //
		private var _showIntelLine:Boolean = true;
		
		private var startPoint:Point;
		
		private var _interactRect:Rectangle; 	  //绘制矩形框
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// public 公有变量声明处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 构造函数，初始化相关工作可以放在里面
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 * Diagram构造函数
		 * 
		 */
		public function Diagram()
		{
			super();
			showIntelLine = true;
			startPoint = new Point();
			addEventListener(MouseEvent.MOUSE_MOVE,onDiagramMouseMove);
			addEventListener(FlexEvent.CREATION_COMPLETE,onCreateComplete);
			addEventListener(KeyboardEvent.KEY_DOWN,onKeyboardDown);
		}//构造函数结束
		
		
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// getter和setter函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/

		/**
		 * 是否显示背景网格
		 */
		[Bindable]
		public function get showGrid():Boolean
		{
			return _showGrid;
		}
		
		/**
		 * @private
		 */
		public function set showGrid(value:Boolean):void
		{
			_showGrid = value;
		}
		
		[Bindable(event="showIntelLineChange")]
		public function get showIntelLine():Boolean
		{
			return _showIntelLine;
		}
		
		public function set showIntelLine(value:Boolean):void
		{
			if( _showIntelLine !== value)
			{
				_showIntelLine = value;
				dispatchEvent(new Event("showIntelLineChange"));
			}
			
			if(decoratorManager){
				decoratorManager.showInteLine = value;
			}
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// 相关事件响应函数和逻辑函数存放处
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 * 获得所选的对象组； 
		 * @return 
		 * 
		 */
		public function getSelectedObjects():ArrayCollection
		{
			return graph.getSelectedObjects();
		}//getSelectedObjects结束
		
		protected function onCreateComplete(event:FlexEvent):void
		{
			decoratorManager = new DecoratorManager(graph,drawingLayer);
			decoratorManager.addDecorator(new AlignmentDecorator());
			decoratorManager.addBackGroundRectDecorator(new DrawMouseMoveRect());
			
//			utils.LicenseHandler.displayWatermark(this.drawingLayer,false);
		}
		
		/**
		 *  
		 * 
		 */
		public function connectObjects():void
		{
			if(getSelectedObjects().length != 2){
				return;
			}
			var startObject:Object=getSelectedObjects()[0];
			var endObject:Object=getSelectedObjects()[1];
			
			connectObj(startObject, endObject);
		}
		
		/**
		 * connect two objects 
		 * @param startObject
		 * @param endObject
		 * 
		 */
		private function connectObj(startObject:Object, endObject:Object):void{
			if(startObject is Node && endObject is Node){
				var link:Link = createLink(Node(startObject),Node(endObject));
				
				//先假设只有一个Graph的情况下；
				var startIndex:int = IVisualElementContainer(Node(startObject).parent).getElementIndex(Node(startObject));
				var endIndex:int = IVisualElementContainer(Node(endObject).parent).getElementIndex(Node(endObject));
				
				Render(startObject).links.addItem(link);
				Render(endObject).links.addItem(link);
				
				this.graph.addElement(link);
				this.graph.setElementIndex(link, Math.min(startIndex,endIndex));
			}
		}
		
		/**
		 * create Link 
		 * @param startNode
		 * @param endNode
		 * @return 
		 * 
		 */
		public function createLink(startNode:Node,endNode:Node):Link{
			var link:Link;
			if(startNode && endNode){
				link = new Link();
				link.setStyle("skinClass",NetworkLinkSkin);
			}	
			
			link.startNode = startNode;
			link.endNode = endNode;
			
			return link;
		}
		/**
		 * 鼠标移动。 
		 * @param event
		 * 
		 */
		protected function onDiagramMouseMove(event:MouseEvent):void
		{
			var object:UIComponent = UIComponent(event.target);
			var hostCom:UIComponent;
			if(object.document.hasOwnProperty("hostComponent")){
				hostCom = object.document["hostComponent"] as UIComponent;
			}
			
			if(hostCom == this){
				return;
			}
			
			if(hostCom is Node){
				if(hostCom is Render){
					if(!AdonerPlayer.playIng){
						AdonerPlayer.play(hostCom as Node);					
					}
				}else if(hostCom is Link){
					if(!AdonerPlayer.playIng){
						AdonerPlayer.play(hostCom as Node);					
					}
				}
			}
		}
		
		/**
		 * 鼠标按下； 
		 * @param event
		 * 
		 */
		protected function onGraphMouseDown(event:Event):void
		{
			if(event.target == graph &&
				event.currentTarget == graph){
				//--清空所选数组；
				graph.clearSelectedObjects();
				graph.dispatchEvent(new SelectionEvent(SelectionEvent.SELECTION_CLEARED));
			}
		}
		
		/**
		 * 
		 * @return 
		 * 
		 */
		protected function getInteractRect():Rectangle
		{
			//確定交互矩形框
			if (this.mouseX - startPoint.x > 0 && this.mouseY - startPoint.y > 0){
				_interactRect=new Rectangle(startPoint.x, startPoint.y, this.mouseX - startPoint.x, this.mouseY - startPoint.y);
			}else if (this.mouseX - startPoint.x < 0 && this.mouseY - startPoint.y < 0){
				_interactRect=new Rectangle(this.mouseX, this.mouseY, startPoint.x - this.mouseX, startPoint.y - this.mouseY);
			}else if (this.mouseX - startPoint.x > 0 && this.mouseY - startPoint.y < 0){
				_interactRect=new Rectangle(startPoint.x, this.mouseY, this.mouseX - startPoint.x, startPoint.y - this.mouseY);
			}else{
				_interactRect=new Rectangle(this.mouseX, startPoint.y, startPoint.x - this.mouseX, this.mouseY - startPoint.y);
			}
			return _interactRect;
			//--获得框选矩形框
		}//getInteractRect结束
		
		/**
		 * 将所有的元素移除 
		 * 
		 */
		public function clear():void
		{
			graph.deleteAll(graph);
			AdonerPlayer.clearDic();
		}//clear结束
		
		/**
		 * 键盘按下； 
		 * @param event
		 * 
		 */
		protected function onKeyboardDown(event:KeyboardEvent):void
		{
			switch (event.keyCode)
			{
				case Keyboard.A: //V键
					graph.selectAll();
					break;
				default:
					break;
			}
		}
		
		
		protected function onDragComplete(event:DragEvent):void
		{
			dispatchEvent(new DiagramEditorEvent(DiagramEditorEvent.EDITOR_CREATE));
		}
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		// override 覆盖函数
		//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
		/**
		 *  partAdded覆盖函数，实例化的时候，对相关引用进行相关事件进行侦听
		 * @param partName
		 * @param instance
		 * 
		 */
		override protected function partAdded(partName:String, instance:Object):void{
			super.partAdded(partName,instance);
			if(instance == graph){
				graph.addEventListener(MouseEvent.MOUSE_DOWN,onGraphMouseDown);
				graph.addEventListener(DragEvent.DRAG_COMPLETE,onDragComplete);
			}
		}
		
		
		/**
		 *  partAdded覆盖函数，实例化的时候，对相关引用进行相关事件进行移除
		 * @param partName
		 * @param instance
		 * 
		 */
		override protected function partRemoved(partName:String, instance:Object):void{
			super.partRemoved(partName,instance);
		}
	}//类结束
}//包结束
